home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / mame.c < prev    next >
C/C++ Source or Header  |  2000-05-20  |  23KB  |  924 lines

  1. #include "driver.h"
  2. #include <ctype.h>
  3. #include <stdarg.h>
  4. #include "ui_text.h" /* LBO 042400 */
  5. #include "artwork.h"
  6.  
  7. static struct RunningMachine machine;
  8. struct RunningMachine *Machine = &machine;
  9. static const struct GameDriver *gamedrv;
  10. static const struct MachineDriver *drv;
  11. static struct osd_bitmap *real_scrbitmap;
  12.  
  13. /* Variables to hold the status of various game options */
  14. struct GameOptions    options;
  15.  
  16. void *record;   /* for -record */
  17. void *playback; /* for -playback */
  18. int mame_debug; /* !0 when -debug option is specified */
  19.  
  20. int bailing;    /* set to 1 if the startup is aborted to prevent multiple error messages */
  21.  
  22. static int settingsloaded;
  23.  
  24. int bitmap_dirty;    /* set by osd_clearbitmap() */
  25.  
  26.  
  27. /* Used in vh_open */
  28. extern unsigned char *spriteram,*spriteram_2;
  29. extern unsigned char *buffered_spriteram,*buffered_spriteram_2;
  30. extern int spriteram_size,spriteram_2_size;
  31.  
  32. int init_machine(void);
  33. void shutdown_machine(void);
  34. int run_machine(void);
  35.  
  36. void overlay_free(void);
  37. void backdrop_free(void);
  38. void overlay_remap(void);
  39. void overlay_draw(struct osd_bitmap *dest,struct osd_bitmap *source);
  40.  
  41.  
  42. #ifdef MAME_DEBUG
  43.  
  44. INLINE int my_stricmp( const char *dst, const char *src)
  45. {
  46.     while (*src && *dst)
  47.     {
  48.         if( tolower(*src) != tolower(*dst) ) return *dst - *src;
  49.         src++;
  50.         dst++;
  51.     }
  52.     return *dst - *src;
  53. }
  54.  
  55. static int validitychecks(void)
  56. {
  57.     int i,j;
  58.     UINT8 a,b;
  59.     int error = 0;
  60.  
  61.  
  62.     a = 0xff;
  63.     b = a + 1;
  64.     if (b > a)    { printf("UINT8 must be 8 bits\n"); error = 1; }
  65.  
  66.     if (sizeof(INT8)   != 1)    { printf("INT8 must be 8 bits\n"); error = 1; }
  67.     if (sizeof(UINT8)  != 1)    { printf("UINT8 must be 8 bits\n"); error = 1; }
  68.     if (sizeof(INT16)  != 2)    { printf("INT16 must be 16 bits\n"); error = 1; }
  69.     if (sizeof(UINT16) != 2)    { printf("UINT16 must be 16 bits\n"); error = 1; }
  70.     if (sizeof(INT32)  != 4)    { printf("INT32 must be 32 bits\n"); error = 1; }
  71.     if (sizeof(UINT32) != 4)    { printf("UINT32 must be 32 bits\n"); error = 1; }
  72.     if (sizeof(INT64)  != 8)    { printf("INT64 must be 64 bits\n"); error = 1; }
  73.     if (sizeof(UINT64) != 8)    { printf("UINT64 must be 64 bits\n"); error = 1; }
  74.  
  75.     for (i = 0;drivers[i];i++)
  76.     {
  77.         const struct RomModule *romp;
  78.         const struct InputPortTiny *inp;
  79.  
  80.         if (drivers[i]->clone_of == drivers[i])
  81.         {
  82.             printf("%s is set as a clone of itself\n",drivers[i]->name);
  83.             error = 1;
  84.         }
  85.  
  86.         if (drivers[i]->clone_of && drivers[i]->clone_of->clone_of)
  87.         {
  88.             if ((drivers[i]->clone_of->clone_of->flags & NOT_A_DRIVER) == 0)
  89.             {
  90.                 printf("%s is a clone of a clone\n",drivers[i]->name);
  91.                 error = 1;
  92.             }
  93.         }
  94.  
  95.         for (j = i+1;drivers[j];j++)
  96.         {
  97.             if (!strcmp(drivers[i]->name,drivers[j]->name))
  98.             {
  99.                 printf("%s is a duplicate name (%s, %s)\n",drivers[i]->name,drivers[i]->source_file,drivers[j]->source_file);
  100.                 error = 1;
  101.             }
  102.             if (!strcmp(drivers[i]->description,drivers[j]->description))
  103.             {
  104.                 printf("%s is a duplicate description (%s, %s)\n",drivers[i]->description,drivers[i]->name,drivers[j]->name);
  105.                 error = 1;
  106.             }
  107.             if (drivers[i]->rom && drivers[i]->rom == drivers[j]->rom
  108.                     && (drivers[i]->flags & NOT_A_DRIVER) == 0
  109.                     && (drivers[j]->flags & NOT_A_DRIVER) == 0)
  110.             {
  111.                 printf("%s and %s use the same ROM set\n",drivers[i]->name,drivers[j]->name);
  112.                 error = 1;
  113.             }
  114.         }
  115.  
  116.         romp = drivers[i]->rom;
  117.  
  118.         if (romp)
  119.         {
  120.             int region_type_used[REGION_MAX];
  121.             int region_length[REGION_MAX];
  122.             const char *last_name = 0;
  123.             int count = -1;
  124.  
  125.             for (j = 0;j < REGION_MAX;j++)
  126.             {
  127.                 region_type_used[j] = 0;
  128.                 region_length[j] = 0;
  129.             }
  130.  
  131.             while (romp->name || romp->offset || romp->length)
  132.             {
  133.                 const char *c;
  134.  
  135.                 if (romp->name == 0 && romp->length == 0)    /* ROM_REGION() */
  136.                 {
  137.                     int type = romp->crc & ~REGIONFLAG_MASK;
  138.  
  139.  
  140.                     count++;
  141.                     if (type && (type >= REGION_MAX || type <= REGION_INVALID))
  142.                     {
  143.                         printf("%s has invalid ROM_REGION type %x\n",drivers[i]->name,type);
  144.                         error = 1;
  145.                     }
  146.  
  147.                     region_type_used[type]++;
  148.                     region_length[type] = region_length[count] = romp->offset;
  149.                 }
  150.                 if (romp->name && romp->name != (char *)-1)
  151.                 {
  152.                     int pre,post;
  153.  
  154.                     last_name = c = romp->name;
  155.                     while (*c)
  156.                     {
  157.                         if (tolower(*c) != *c)
  158.                         {
  159.                             printf("%s has upper case ROM name %s\n",drivers[i]->name,romp->name);
  160.                             error = 1;
  161.                         }
  162.                         c++;
  163.                     }
  164.  
  165.                     c = romp->name;
  166.                     pre = 0;
  167.                     post = 0;
  168.                     while (*c && *c != '.')
  169.                     {
  170.                         pre++;
  171.                         c++;
  172.                     }
  173.                     while (*c)
  174.                     {
  175.                         post++;
  176.                         c++;
  177.                     }
  178.                     if (pre > 8 || post > 4)
  179.                     {
  180.                         printf("%s has >8.3 ROM name %s\n",drivers[i]->name,romp->name);
  181.                         error = 1;
  182.                     }
  183.                 }
  184.                 if (romp->length != 0)                        /* ROM_LOAD_XXX() */
  185.                 {
  186.                     if (romp->offset + (romp->length & ~ROMFLAG_MASK) > region_length[count])
  187.                     {
  188.                         printf("%s has ROM %s extending past the defined memory region\n",drivers[i]->name,last_name);
  189.                         error = 1;
  190.                     }
  191.                 }
  192.                 romp++;
  193.             }
  194.  
  195.             for (j = 1;j < REGION_MAX;j++)
  196.             {
  197.                 if (region_type_used[j] > 1)
  198.                 {
  199.                     printf("%s has duplicated ROM_REGION type %x\n",drivers[i]->name,j);
  200.                     error = 1;
  201.                 }
  202.             }
  203.  
  204.  
  205.             if (drivers[i]->drv->gfxdecodeinfo)
  206.             {
  207.                 for (j = 0;j < MAX_GFX_ELEMENTS && drivers[i]->drv->gfxdecodeinfo[j].memory_region != -1;j++)
  208.                 {
  209.                     int len,avail,k,start;
  210.                     int type = drivers[i]->drv->gfxdecodeinfo[j].memory_region;
  211.  
  212.  
  213. /*
  214.                     if (type && (type >= REGION_MAX || type <= REGION_INVALID))
  215.                     {
  216.                         printf("%s has invalid memory region for gfx[%d]\n",drivers[i]->name,j);
  217.                         error = 1;
  218.                     }
  219. */
  220.  
  221.                     if (!IS_FRAC(drivers[i]->drv->gfxdecodeinfo[j].gfxlayout->total))
  222.                     {
  223.                         start = 0;
  224.                         for (k = 0;k < MAX_GFX_PLANES;k++)
  225.                         {
  226.                             if (drivers[i]->drv->gfxdecodeinfo[j].gfxlayout->planeoffset[k] > start)
  227.                                 start = drivers[i]->drv->gfxdecodeinfo[j].gfxlayout->planeoffset[k];
  228.                         }
  229.                         start &= ~(drivers[i]->drv->gfxdecodeinfo[j].gfxlayout->charincrement-1);
  230.                         len = drivers[i]->drv->gfxdecodeinfo[j].gfxlayout->total *
  231.                                 drivers[i]->drv->gfxdecodeinfo[j].gfxlayout->charincrement;
  232.                         avail = region_length[type]
  233.                                 - (drivers[i]->drv->gfxdecodeinfo[j].start & ~(drivers[i]->drv->gfxdecodeinfo[j].gfxlayout->charincrement/8-1));
  234.                         if ((start + len) / 8 > avail)
  235.                         {
  236.                             printf("%s has gfx[%d] extending past allocated memory\n",drivers[i]->name,j);
  237.                             error = 1;
  238.                         }
  239.                     }
  240.                 }
  241.             }
  242.         }
  243.  
  244.  
  245.         inp = drivers[i]->input_ports;
  246.  
  247.         if (inp)
  248.         {
  249.             while (inp->type != IPT_END)
  250.             {
  251.                 if (inp->name && inp->name != IP_NAME_DEFAULT)
  252.                 {
  253.                     j = 0;
  254.  
  255.                     while (ipdn_defaultstrings[j] != DEF_STR( Unknown ))
  256.                     {
  257.                         if (inp->name == ipdn_defaultstrings[j]) break;
  258.                         else if (!my_stricmp(inp->name,ipdn_defaultstrings[j]))
  259.                         {
  260.                             printf("%s must use DEF_STR( %s )\n",drivers[i]->name,inp->name);
  261.                             error = 1;
  262.                         }
  263.                         j++;
  264.                     }
  265.  
  266.                     if (inp->name == DEF_STR( On ) && (inp+1)->name == DEF_STR( Off ))
  267.                     {
  268.                         printf("%s has inverted Off/On dipswitch order\n",drivers[i]->name);
  269.                         error = 1;
  270.                     }
  271.  
  272.                     if (inp->name == DEF_STR( Yes ) && (inp+1)->name == DEF_STR( No ))
  273.                     {
  274.                         printf("%s has inverted No/Yes dipswitch order\n",drivers[i]->name);
  275.                         error = 1;
  276.                     }
  277.  
  278.                     if (!my_stricmp(inp->name,"table"))
  279.                     {
  280.                         printf("%s must use DEF_STR( Cocktail ), not %s\n",drivers[i]->name,inp->name);
  281.                         error = 1;
  282.                     }
  283.  
  284.                     if (inp->name == DEF_STR( Cocktail ) && (inp+1)->name == DEF_STR( Upright ))
  285.                     {
  286.                         printf("%s has inverted Upright/Cocktail dipswitch order\n",drivers[i]->name);
  287.                         error = 1;
  288.                     }
  289.  
  290.                     if (inp->name >= DEF_STR( 9C_1C ) && inp->name <= DEF_STR( Free_Play )
  291.                             && (inp+1)->name >= DEF_STR( 9C_1C ) && (inp+1)->name <= DEF_STR( Free_Play )
  292.                             && inp->name >= (inp+1)->name)
  293.                     {
  294.                         printf("%s has unsorted coinage %s > %s\n",drivers[i]->name,inp->name,(inp+1)->name);
  295.                         error = 1;
  296.                     }
  297.  
  298.                     if (inp->name == DEF_STR( Flip_Screen ) && (inp+1)->name != DEF_STR( Off ))
  299.                     {
  300.                         printf("%s has wrong Flip Screen option %s\n",drivers[i]->name,(inp+1)->name);
  301.                         error = 1;
  302.                     }
  303.  
  304.                 }
  305.  
  306.                 inp++;
  307.             }
  308.         }
  309.     }
  310.  
  311.     return error;
  312. }
  313. #endif
  314.  
  315.  
  316.  
  317.  
  318. int run_game(int game)
  319. {
  320.     int err;
  321.  
  322.  
  323. #ifdef MAME_DEBUG
  324.     /* validity checks */
  325.     if (validitychecks()) return 1;
  326. #endif
  327.  
  328.  
  329.     /* copy some settings into easier-to-handle variables */
  330.     record     = options.record;
  331.     playback   = options.playback;
  332.     mame_debug = options.mame_debug;
  333.  
  334.     Machine->gamedrv = gamedrv = drivers[game];
  335.     Machine->drv = drv = gamedrv->drv;
  336.  
  337.     /* copy configuration */
  338.     if (options.color_depth == 16 ||
  339.             (options.color_depth != 8 && (Machine->gamedrv->flags & GAME_REQUIRES_16BIT)))
  340.         Machine->color_depth = 16;
  341.     else
  342.         Machine->color_depth = 8;
  343.     Machine->sample_rate = options.samplerate;
  344.  
  345.     /* get orientation right */
  346.     Machine->orientation = gamedrv->flags & ORIENTATION_MASK;
  347.     Machine->ui_orientation = ROT0;
  348.     if (options.norotate)
  349.         Machine->orientation = ROT0;
  350.     if (options.ror)
  351.     {
  352.         /* if only one of the components is inverted, switch them */
  353.         if ((Machine->orientation & ROT180) == ORIENTATION_FLIP_X ||
  354.                 (Machine->orientation & ROT180) == ORIENTATION_FLIP_Y)
  355.             Machine->orientation ^= ROT180;
  356.  
  357.         Machine->orientation ^= ROT90;
  358.  
  359.         /* if only one of the components is inverted, switch them */
  360.         if ((Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_X ||
  361.                 (Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_Y)
  362.             Machine->ui_orientation ^= ROT180;
  363.  
  364.         Machine->ui_orientation ^= ROT90;
  365.     }
  366.     if (options.rol)
  367.     {
  368.         /* if only one of the components is inverted, switch them */
  369.         if ((Machine->orientation & ROT180) == ORIENTATION_FLIP_X ||
  370.                 (Machine->orientation & ROT180) == ORIENTATION_FLIP_Y)
  371.             Machine->orientation ^= ROT180;
  372.  
  373.         Machine->orientation ^= ROT270;
  374.  
  375.         /* if only one of the components is inverted, switch them */
  376.         if ((Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_X ||
  377.                 (Machine->ui_orientation & ROT180) == ORIENTATION_FLIP_Y)
  378.             Machine->ui_orientation ^= ROT180;
  379.  
  380.         Machine->ui_orientation ^= ROT270;
  381.     }
  382.     if (options.flipx)
  383.     {
  384.         Machine->orientation ^= ORIENTATION_FLIP_X;
  385.         Machine->ui_orientation ^= ORIENTATION_FLIP_X;
  386.     }
  387.     if (options.flipy)
  388.     {
  389.         Machine->orientation ^= ORIENTATION_FLIP_Y;
  390.         Machine->ui_orientation ^= ORIENTATION_FLIP_Y;
  391.     }
  392.  
  393.     set_pixel_functions();
  394.  
  395.     /* Do the work*/
  396.     err = 1;
  397.     bailing = 0;
  398.  
  399.     #ifdef MESS
  400.     if (get_filenames())
  401.         return err;
  402.     #endif
  403.  
  404.     if (osd_init() == 0)
  405.     {
  406.         if (init_machine() == 0)
  407.         {
  408.             if (run_machine() == 0)
  409.                 err = 0;
  410.             else if (!bailing)
  411.             {
  412.                 bailing = 1;
  413.                 printf("Unable to start machine emulation\n");
  414.             }
  415.  
  416.             shutdown_machine();
  417.         }
  418.         else if (!bailing)
  419.         {
  420.             bailing = 1;
  421.             printf("Unable to initialize machine emulation\n");
  422.         }
  423.  
  424.         osd_exit();
  425.     }
  426.     else if (!bailing)
  427.     {
  428.         bailing = 1;
  429.         printf ("Unable to initialize system\n");
  430.     }
  431.  
  432.     return err;
  433. }
  434.  
  435.  
  436.  
  437. /***************************************************************************
  438.  
  439.   Initialize the emulated machine (load the roms, initialize the various
  440.   subsystems...). Returns 0 if successful.
  441.  
  442. ***************************************************************************/
  443. int init_machine(void)
  444. {
  445.     int i;
  446.  
  447.     /* LBO 042400 start */
  448.     if (uistring_init (options.language_file) != 0)
  449.         goto out;
  450.     /* LBO 042400 end */
  451.  
  452.     if (code_init() != 0)
  453.         goto out;
  454.  
  455.     for (i = 0;i < MAX_MEMORY_REGIONS;i++)
  456.     {
  457.         Machine->memory_region[i] = 0;
  458.         Machine->memory_region_length[i] = 0;
  459.         Machine->memory_region_type[i] = 0;
  460.     }
  461.  
  462.     if (gamedrv->input_ports)
  463.     {
  464.         Machine->input_ports = input_port_allocate(gamedrv->input_ports);
  465.         if (!Machine->input_ports)
  466.             goto out_code;
  467.         Machine->input_ports_default = input_port_allocate(gamedrv->input_ports);
  468.         if (!Machine->input_ports_default)
  469.         {
  470.             input_port_free(Machine->input_ports);
  471.             Machine->input_ports = 0;
  472.             goto out_code;
  473.         }
  474.     }
  475.  
  476.     #ifdef MESS
  477.     if (!gamedrv->rom)
  478.     {
  479.         logerror("Going to load_next tag\n");
  480.         goto load_next;
  481.     }
  482.     #endif
  483.  
  484.     if (readroms() != 0)
  485.         goto out_free;
  486.  
  487.     #ifdef MESS
  488.     load_next:
  489.         if (init_devices(gamedrv))
  490.             goto out_free;
  491.     #endif
  492.  
  493.     /* Mish:  Multi-session safety - set spriteram size to zero before memory map is set up */
  494.     spriteram_size=spriteram_2_size=0;
  495.  
  496.     /* first of all initialize the memory handlers, which could be used by the */
  497.     /* other initialization routines */
  498.     cpu_init();
  499.  
  500.     /* load input ports settings (keys, dip switches, and so on) */
  501.     settingsloaded = load_input_port_settings();
  502.  
  503.     if( !memory_init() )
  504.         goto out_free;
  505.  
  506.     if (gamedrv->driver_init) (*gamedrv->driver_init)();
  507.  
  508.     return 0;
  509.  
  510. out_free:
  511.     input_port_free(Machine->input_ports);
  512.     Machine->input_ports = 0;
  513.     input_port_free(Machine->input_ports_default);
  514.     Machine->input_ports_default = 0;
  515. out_code:
  516.     code_close();
  517. out:
  518.     return 1;
  519. }
  520.  
  521.  
  522.  
  523. void shutdown_machine(void)
  524. {
  525.     int i;
  526.  
  527.  
  528.     #ifdef MESS
  529.     exit_devices();
  530.     #endif
  531.  
  532.     /* ASG 971007 free memory element map */
  533.     memory_shutdown();
  534.  
  535.     /* free the memory allocated for ROM and RAM */
  536.     for (i = 0;i < MAX_MEMORY_REGIONS;i++)
  537.     {
  538.         free(Machine->memory_region[i]);
  539.         Machine->memory_region[i] = 0;
  540.         Machine->memory_region_length[i] = 0;
  541.         Machine->memory_region_type[i] = 0;
  542.     }
  543.  
  544.     /* free the memory allocated for input ports definition */
  545.     input_port_free(Machine->input_ports);
  546.     Machine->input_ports = 0;
  547.     input_port_free(Machine->input_ports_default);
  548.     Machine->input_ports_default = 0;
  549.  
  550.     code_close();
  551.  
  552.     uistring_shutdown (); /* LBO 042400 */
  553. }
  554.  
  555.  
  556.  
  557. static void vh_close(void)
  558. {
  559.     int i;
  560.  
  561.  
  562.     for (i = 0;i < MAX_GFX_ELEMENTS;i++)
  563.     {
  564.         freegfx(Machine->gfx[i]);
  565.         Machine->gfx[i] = 0;
  566.     }
  567.     freegfx(Machine->uifont);
  568.     Machine->uifont = 0;
  569.     osd_close_display();
  570.     palette_stop();
  571.  
  572.     if (drv->video_attributes & VIDEO_BUFFERS_SPRITERAM) {
  573.         if (buffered_spriteram) free(buffered_spriteram);
  574.         if (buffered_spriteram_2) free(buffered_spriteram_2);
  575.         buffered_spriteram=NULL;
  576.         buffered_spriteram_2=NULL;
  577.     }
  578. }
  579.  
  580.  
  581.  
  582. static int vh_open(void)
  583. {
  584.     int i;
  585.  
  586.  
  587.     for (i = 0;i < MAX_GFX_ELEMENTS;i++) Machine->gfx[i] = 0;
  588.     Machine->uifont = 0;
  589.  
  590.     if (palette_start() != 0)
  591.     {
  592.         vh_close();
  593.         return 1;
  594.     }
  595.  
  596.  
  597.     /* convert the gfx ROMs into character sets. This is done BEFORE calling the driver's */
  598.     /* convert_color_prom() routine (in palette_init()) because it might need to check the */
  599.     /* Machine->gfx[] data */
  600.     if (drv->gfxdecodeinfo)
  601.     {
  602.         for (i = 0;i < MAX_GFX_ELEMENTS && drv->gfxdecodeinfo[i].memory_region != -1;i++)
  603.         {
  604.             int reglen = 8*memory_region_length(drv->gfxdecodeinfo[i].memory_region);
  605.             struct GfxLayout glcopy;
  606.             int j;
  607.  
  608.  
  609.             memcpy(&glcopy,drv->gfxdecodeinfo[i].gfxlayout,sizeof(glcopy));
  610.  
  611.             if (IS_FRAC(glcopy.total))
  612.                 glcopy.total = reglen / glcopy.charincrement * FRAC_NUM(glcopy.total) / FRAC_DEN(glcopy.total);
  613.             for (j = 0;j < MAX_GFX_PLANES;j++)
  614.             {
  615.                 if (IS_FRAC(glcopy.planeoffset[j]))
  616.                 {
  617.                     glcopy.planeoffset[j] = FRAC_OFFSET(glcopy.planeoffset[j]) +
  618.                             reglen * FRAC_NUM(glcopy.planeoffset[j]) / FRAC_DEN(glcopy.planeoffset[j]);
  619.                 }
  620.             }
  621.             for (j = 0;j < MAX_GFX_SIZE;j++)
  622.             {
  623.                 if (IS_FRAC(glcopy.xoffset[j]))
  624.                 {
  625.                     glcopy.xoffset[j] = FRAC_OFFSET(glcopy.xoffset[j]) +
  626.                             reglen * FRAC_NUM(glcopy.xoffset[j]) / FRAC_DEN(glcopy.xoffset[j]);
  627.                 }
  628.                 if (IS_FRAC(glcopy.yoffset[j]))
  629.                 {
  630.                     glcopy.yoffset[j] = FRAC_OFFSET(glcopy.yoffset[j]) +
  631.                             reglen * FRAC_NUM(glcopy.yoffset[j]) / FRAC_DEN(glcopy.yoffset[j]);
  632.                 }
  633.             }
  634.  
  635.             if ((Machine->gfx[i] = decodegfx(memory_region(drv->gfxdecodeinfo[i].memory_region)
  636.                     + drv->gfxdecodeinfo[i].start,
  637.                     &glcopy)) == 0)
  638.             {
  639.                 vh_close();
  640.  
  641.                 bailing = 1;
  642.                 printf("Out of memory decoding gfx\n");
  643.  
  644.                 return 1;
  645.             }
  646.             if (Machine->remapped_colortable)
  647.                 Machine->gfx[i]->colortable = &Machine->remapped_colortable[drv->gfxdecodeinfo[i].color_codes_start];
  648.             Machine->gfx[i]->total_colors = drv->gfxdecodeinfo[i].total_color_codes;
  649.         }
  650.     }
  651.  
  652.  
  653.     /* create the display bitmap, and allocate the palette */
  654.     if ((Machine->scrbitmap = osd_create_display(
  655.             drv->screen_width,drv->screen_height,
  656.             Machine->color_depth,
  657.             drv->video_attributes)) == 0)
  658.     {
  659.         vh_close();
  660.         return 1;
  661.     }
  662.  
  663.     /* create spriteram buffers if necessary */
  664.     if (drv->video_attributes & VIDEO_BUFFERS_SPRITERAM) {
  665.         if (spriteram_size!=0) {
  666.             buffered_spriteram= malloc(spriteram_size);
  667.             if (!buffered_spriteram) { vh_close(); return 1; }
  668.             if (spriteram_2_size!=0) buffered_spriteram_2 = malloc(spriteram_2_size);
  669.             if (spriteram_2_size && !buffered_spriteram_2) { vh_close(); return 1; }
  670.         } else {
  671.             logerror("vh_open():  Video buffers spriteram but spriteram_size is 0\n");
  672.             buffered_spriteram=NULL;
  673.             buffered_spriteram_2=NULL;
  674.         }
  675.     }
  676.  
  677.     /* build our private user interface font */
  678.     /* This must be done AFTER osd_create_display() so the function knows the */
  679.     /* resolution we are running at and can pick a different font depending on it. */
  680.     /* It must be done BEFORE palette_init() because that will also initialize */
  681.     /* (through osd_allocate_colors()) the uifont colortable. */
  682.     if ((Machine->uifont = builduifont()) == 0)
  683.     {
  684.         vh_close();
  685.         return 1;
  686.     }
  687.  
  688.     /* initialize the palette - must be done after osd_create_display() */
  689.     if (palette_init())
  690.     {
  691.         vh_close();
  692.         return 1;
  693.     }
  694.  
  695.     return 0;
  696. }
  697.  
  698.  
  699.  
  700. /***************************************************************************
  701.  
  702.   This function takes care of refreshing the screen, processing user input,
  703.   and throttling the emulation speed to obtain the required frames per second.
  704.  
  705. ***************************************************************************/
  706.  
  707. int need_to_clear_bitmap;    /* set by the user interface */
  708.  
  709. int updatescreen(void)
  710. {
  711.     /* update sound */
  712.     sound_update();
  713.  
  714.     if (osd_skip_this_frame() == 0)
  715.     {
  716.         profiler_mark(PROFILER_VIDEO);
  717.         if (need_to_clear_bitmap)
  718.         {
  719.             osd_clearbitmap(real_scrbitmap);
  720.             need_to_clear_bitmap = 0;
  721.         }
  722.         draw_screen(bitmap_dirty);    /* update screen */
  723.         bitmap_dirty = 0;
  724.         profiler_mark(PROFILER_END);
  725.     }
  726.  
  727.     /* the user interface must be called between vh_update() and osd_update_video_and_audio(), */
  728.     /* to allow it to overlay things on the game display. We must call it even */
  729.     /* if the frame is skipped, to keep a consistent timing. */
  730.     if (handle_user_interface(real_scrbitmap))
  731.         /* quit if the user asked to */
  732.         return 1;
  733.  
  734.     update_video_and_audio();
  735.  
  736.     if (drv->vh_eof_callback) (*drv->vh_eof_callback)();
  737.  
  738.     return 0;
  739. }
  740.  
  741.  
  742. /***************************************************************************
  743.  
  744.   Draw screen with overlays and backdrops (not yet)
  745.  
  746. ***************************************************************************/
  747.  
  748. void draw_screen(int _bitmap_dirty)
  749. {
  750.     if (_bitmap_dirty)  overlay_remap();
  751.  
  752.     (*Machine->drv->vh_update)(Machine->scrbitmap,_bitmap_dirty);  /* update screen */
  753.  
  754.     if (artwork_overlay)
  755.     {
  756.         overlay_draw(overlay_real_scrbitmap, Machine->scrbitmap);
  757.     }
  758. }
  759.  
  760.  
  761. /***************************************************************************
  762.  
  763.   Calls OSD layer handling overlays and backdrops (not yet)
  764.  
  765. ***************************************************************************/
  766. void update_video_and_audio(void)
  767. {
  768.     struct osd_bitmap *save = Machine->scrbitmap;
  769.     Machine->scrbitmap = real_scrbitmap;
  770.  
  771.     osd_update_video_and_audio();
  772.  
  773.     Machine->scrbitmap = save;
  774. }
  775.  
  776.  
  777. /***************************************************************************
  778.  
  779.   Run the emulation. Start the various subsystems and the CPU emulation.
  780.   Returns non zero in case of error.
  781.  
  782. ***************************************************************************/
  783. int run_machine(void)
  784. {
  785.     int res = 1;
  786.  
  787.  
  788.     if (vh_open() == 0)
  789.     {
  790.         tilemap_init();
  791.         sprite_init();
  792.         gfxobj_init();
  793.         if (drv->vh_start == 0 || (*drv->vh_start)() == 0)      /* start the video hardware */
  794.         {
  795.             if (sound_start() == 0) /* start the audio hardware */
  796.             {
  797.                 int    region;
  798.  
  799.                 real_scrbitmap = artwork_overlay ? overlay_real_scrbitmap : Machine->scrbitmap;
  800.  
  801.                 /* free memory regions allocated with REGIONFLAG_DISPOSE (typically gfx roms) */
  802.                 for (region = 0; region < MAX_MEMORY_REGIONS; region++)
  803.                 {
  804.                     if (Machine->memory_region_type[region] & REGIONFLAG_DISPOSE)
  805.                     {
  806.                         int i;
  807.  
  808.                         /* invalidate contents to avoid subtle bugs */
  809.                         for (i = 0;i < memory_region_length(region);i++)
  810.                             memory_region(region)[i] = rand();
  811.                         free(Machine->memory_region[region]);
  812.                         Machine->memory_region[region] = 0;
  813.                     }
  814.                 }
  815.  
  816.                 if (settingsloaded == 0)
  817.                 {
  818.                     /* if there is no saved config, it must be first time we run this game, */
  819.                     /* so show the disclaimer. */
  820.                     if (showcopyright(real_scrbitmap)) goto userquit;
  821.                 }
  822.  
  823.                 if (showgamewarnings(real_scrbitmap) == 0)  /* show info about incorrect behaviour (wrong colors etc.) */
  824.                 {
  825.                     /* shut down the leds (work around Allegro hanging bug in the DOS port) */
  826.                     osd_led_w(0,1);
  827.                     osd_led_w(1,1);
  828.                     osd_led_w(2,1);
  829.                     osd_led_w(3,1);
  830.                     osd_led_w(0,0);
  831.                     osd_led_w(1,0);
  832.                     osd_led_w(2,0);
  833.                     osd_led_w(3,0);
  834.  
  835.                     init_user_interface();
  836.  
  837.                     /* disable cheat if no roms */
  838.                     if (!gamedrv->rom) options.cheat = 0;
  839.  
  840.                     if (options.cheat) InitCheat();
  841.  
  842.                     if (drv->nvram_handler)
  843.                     {
  844.                         void *f;
  845.  
  846.                         f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_NVRAM,0);
  847.                         (*drv->nvram_handler)(f,0);
  848.                         if (f) osd_fclose(f);
  849.                     }
  850.  
  851.                     cpu_run();      /* run the emulation! */
  852.  
  853.                     if (drv->nvram_handler)
  854.                     {
  855.                         void *f;
  856.  
  857.                         if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_NVRAM,1)) != 0)
  858.                         {
  859.                             (*drv->nvram_handler)(f,1);
  860.                             osd_fclose(f);
  861.                         }
  862.                     }
  863.  
  864.                     if (options.cheat) StopCheat();
  865.  
  866.                     /* save input ports settings */
  867.                     save_input_port_settings();
  868.                 }
  869.  
  870. userquit:
  871.                 /* the following MUST be done after hiscore_save() otherwise */
  872.                 /* some 68000 games will not work */
  873.                 sound_stop();
  874.                 if (drv->vh_stop) (*drv->vh_stop)();
  875.                 overlay_free();
  876.                 backdrop_free();
  877.  
  878.                 res = 0;
  879.             }
  880.             else if (!bailing)
  881.             {
  882.                 bailing = 1;
  883.                 printf("Unable to start audio emulation\n");
  884.             }
  885.         }
  886.         else if (!bailing)
  887.         {
  888.             bailing = 1;
  889.             printf("Unable to start video emulation\n");
  890.         }
  891.  
  892.         gfxobj_close();
  893.         sprite_close();
  894.         tilemap_close();
  895.         vh_close();
  896.     }
  897.     else if (!bailing)
  898.     {
  899.         bailing = 1;
  900.         printf("Unable to start video emulation\n");
  901.     }
  902.  
  903.     return res;
  904. }
  905.  
  906.  
  907.  
  908. int mame_highscore_enabled(void)
  909. {
  910.     /* disable high score when record/playback is on */
  911.     if (record != 0 || playback != 0) return 0;
  912.  
  913.     /* disable high score when cheats are used */
  914.     if (he_did_cheat != 0) return 0;
  915.  
  916. #ifdef MAME_NET
  917.     /* disable high score when playing network game */
  918.     /* (this forces all networked machines to start from the same state!) */
  919.     if (net_active()) return 0;
  920. #endif /* MAME_NET */
  921.  
  922.     return 1;
  923. }
  924.